package com.cbank.utils;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.cbank.platform.config.SystemGlobals;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.util.Auth;
import com.qiniu.util.Etag;
import com.qiniu.util.StringMap;

public class QiniuUtils {

	private static final Logger logger = Logger.getLogger(QiniuUtils.class);

	private static final String accessKey = SystemGlobals.getPreference("qiniu.acceskey");
	private static final String secretKey = SystemGlobals.getPreference("qiniu.secretkey");
	private static final String bucket = SystemGlobals.getPreference("qiniu.bucket");
	private static final String bucketURL = SystemGlobals.getPreference("qiniu.bucketUrl");
	private static final String expireStr = SystemGlobals.getPreference("qiniu.expire");
	// 创建上传对象
	private static UploadManager uploadManager = new UploadManager(getConfiguration());

	private static Auth getAuth() {
		return Auth.create(accessKey, secretKey);
	}

	private static Configuration getConfiguration() {
		Zone z = Zone.zone1();
		Configuration c = new Configuration(z);
		return c;
	}

	/**
	 * 
	 * @param key
	 * @param overFlag
	 *            是否同名 覆盖
	 * @return
	 */
	public static String getUpToken(String key, boolean overFlag) {
		long expire = 1800;
		if (StringUtils.isNotBlank(expireStr)) {
			expire = Long.valueOf(expireStr);
		}
		Auth auth = getAuth();
		if (!overFlag)
			return auth.uploadToken(bucket, key, expire, new StringMap().put("insertOnly", 1));

		return auth.uploadToken(bucket, key, expire, new StringMap());
	}

	public static String upload(String filePath, String key) {
		try {
			// 调用put方法上传
			// 调用put方法上传，这里指定的key和上传策略中的key要一致
			String token = getUpToken(key, true);
			Response res = uploadManager.put(filePath, key, token);
			// 打印返回的信息
			String url = bucketURL;
			// 打印返回的信息
			if (res.isOK()) {
				JSONObject json = JSONObject.parseObject(res.bodyString());
				String resultKey = json.getString("key");
				url = url + resultKey;
				return url;
			} else {
				return null;
			}
		} catch (Exception e) {
			logger.error("qiniu upload error:", e);
		}
		return null;
	}

	public static String upload(byte[] file, String key) {
		try {
			// 调用put方法上传
			String url = bucketURL;
			Response res = uploadManager.put(file, key, getUpToken(key, true));
			// 打印返回的信息
			if (res.isOK()) {
				JSONObject json = JSONObject.parseObject(res.bodyString());
				String resultKey = json.getString("key");
				url = url + "/" + resultKey;
				logger.info("qiniu upload OK:" + url);
				return url;
			} else {
				logger.info("qiniu upload failed:" + url);
				return "";
			}
		} catch (Exception e) {
			logger.error("qiniu upload error:", e);
		}
		return "";
	}

	/**
	 * 从url地址中获取文件名
	 * 
	 * @author:qiuchen
	 * @createTime:2012-6-12
	 * @param url
	 * @return
	 */
	public static String getFileNameByUrl(String url) {
		int lastNo = url.lastIndexOf("/"); // 最后一个"/"的索引
		if (url.substring(lastNo).lastIndexOf(".") == -1) { // one webpage
			return url;
		} else {
			if ("".equals(url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf(".")))) {
				getFileNameByUrl(url.substring(0, url.lastIndexOf("/")));
			} else {
				return url.substring(url.lastIndexOf("/") + 1);
			}
		}
		return url;
	}

	public static boolean downloadFile(String url, String savePath) {
		try {
			HttpResponse response = HttpClientUtils.getInvoke(url, null, null);
			int state = response.getStatusLine().getStatusCode();
			if (state == HttpStatus.SC_OK) { // 状态码=200
				// 获得服务器响应的信息(除head部分,源代码中是看不到的)
				HttpEntity entity = response.getEntity();

				// 获取输入流
				InputStream input = entity.getContent();
				FileOutputStream bout = new FileOutputStream(savePath);

				byte[] buffer = new byte[1024 * 100000];
				int read = 0;

				while ((read = input.read(buffer)) > 0) {
					bout.write(buffer, 0, read);
				}
				input.close(); // 关闭输入流
				bout.close(); // 关闭输出流
				return true;

			} else {
				logger.info("read error");
			}
		} catch (Exception e) {
			logger.error("downloadFile error:", e);
		}
		return false;

	}

	/**
	 * 根据key获取文件信息
	 * 
	 * @param path
	 * 
	 * @return
	 * @throws Exception
	 */
	public static FileInfo getFileInfoByKey(String key) {
		BucketManager bucketManager = new BucketManager(getAuth(), getConfiguration());
		FileInfo info = null;
		try {
			// 调用stat()方法获取文件的信息
			info = bucketManager.stat(bucket, key);
		} catch (QiniuException e) {
			// 捕获异常信息
			Response r = e.response;
			System.out.println(r.toString());
			return info;
		}
		return info;
	}

	public static void main(String[] args) throws Exception {
		String key = "4寸8cm高.jpg";
		FileInfo info = getFileInfoByKey(key);
		if (null != info) {
			System.out.println(info.key);
		} else {
			System.out.println("-------------");

		}
	}
	
	/**
	 * 获取七牛视频文件唯一的hash值
	 * 
	 * @param in
	 *            数据输入流
	 * @param len
	 *            数据流长度
	 * @return 数据流的etag值
	 * @throws IOException
	 */
	public static String getQiniuHashCode(InputStream in, long le) {
		try {
			return Etag.stream(in, le);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

}
